package com.ytjj.qmyx.admin.service.impl;

import com.ytjj.common.constants.CopyWriterConstant;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.utils.CopyWriterConfigUtil;
import com.ytjj.qmyx.admin.constants.SysConfigConstants;
import com.ytjj.qmyx.admin.dao.MenuDao;
import com.ytjj.qmyx.admin.mapper.MenuMapper;
import com.ytjj.qmyx.admin.model.Menu;
import com.ytjj.qmyx.admin.model.MenuExample;
import com.ytjj.qmyx.admin.model.request.ButtonRequest;
import com.ytjj.qmyx.admin.model.response.MenuTreeResponse;
import com.ytjj.qmyx.admin.service.MenuService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl implements MenuService {

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private MenuDao menuDao;

    @Resource
    private CopyWriterConfigUtil copyWriterConfigUtil;

    @Override
    public int create(Menu menu) {
        menu.setCreateTime(new Date());
        menu.setType(SysConfigConstants.Menu_Config.TYPE_1);
        menu.setIsPermission(SysConfigConstants.STATUS_0);
        menu.setApiCode(menu.getApiCode().trim());
        menu.setMenuCode(menu.getMenuCode().trim());
        // updateLevel(menu);
        return menuMapper.insert(menu);
    }

    @Override
    public int update(Menu menu) {
        // updateLevel(menu);
        menu.setUpdateTime(new Date());
        return menuMapper.updateByPrimaryKeySelective(menu);
    }

    @Override
    public Menu getMenuById(Integer id) {
        return menuMapper.selectByPrimaryKey(id);
    }

    @Override
    public int delete(Integer id) {
        List<Integer> ids = new ArrayList<>();
        this.getChildrenById(id,ids);
        // 批量删除所有子菜单节点
        if(!CollectionUtils.isEmpty(ids)){
            menuDao.deleteChildrens(ids);
        }
        return menuMapper.deleteByPrimaryKey(id);
    }

    private void getChildrenById(Integer id, List<Integer> ids){
        MenuExample menuExample = new MenuExample();
        menuExample.createCriteria().andMenuPreCodeEqualTo(String.valueOf(id));
        List<Menu> menus = menuMapper.selectByExample(menuExample);
        if(!CollectionUtils.isEmpty(menus)){
            for (Menu menu : menus){
                ids.add(menu.getId());
                getChildrenById(menu.getId(),ids);
            }
        }
    }

    @Override
    public List<MenuTreeResponse> treeList() {
        List<Menu> menuList = menuDao.selectList();
        List<MenuTreeResponse> result = menuList.stream()
                .filter(menu -> StringUtils.isBlank(menu.getMenuPreCode()))
                .map(menu -> covertMenuNode(menu, menuList)).collect(Collectors.toList());
        return result;
    }

    @Override
    public int updatePerm(Integer id) {
        Menu menu = menuMapper.selectByPrimaryKey(id);
        if(menu.getIsPermission().equals(SysConfigConstants.STATUS_1)){
            menu.setIsPermission(SysConfigConstants.STATUS_0);
        }else{
            menu.setIsPermission(SysConfigConstants.STATUS_1);
        }
        menu.setUpdateTime(new Date());
        return menuMapper.updateByPrimaryKeySelective(menu);
    }

    @Override
    public int updateTreeList(Integer checkedId, Integer pId) {
        // 拖拽的菜单节点
        Menu menu = menuMapper.selectByPrimaryKey(checkedId);
        if(pId == null || pId == 0){
            menu.setMenuPreCode("");
        }else{
            menu.setMenuPreCode(String.valueOf(pId));
        }
        return menuMapper.updateByPrimaryKeySelective(menu);
    }

    @Override
    public List<Menu> buttonList(ButtonRequest buttonRequest) {
        List<Menu> menus = menuDao.selectButtonList(buttonRequest);
        return menus;
    }

    @Override
    public List<Menu> queryChildrenList() {
        MenuExample menuExample = new MenuExample();
        menuExample.createCriteria().andTypeEqualTo((byte)1);
        List<Menu> menus = menuMapper.selectByExample(menuExample).stream()
                .filter(item -> StringUtils.isNotBlank(item.getMenuPreCode())).collect(Collectors.toList());

        List<Menu> children = new ArrayList<>();
        for(Menu menu : menus){
            MenuExample criteria = new MenuExample();
            criteria.createCriteria().andTypeEqualTo((byte)1).andMenuPreCodeEqualTo(String.valueOf(menu.getId()));
            List<Menu> counts = menuMapper.selectByExample(criteria);
            if(counts.size()==0){
                children.add(menu);
            }
        }
        return children;
    }

    @Override
    public int createButton(Menu menu) {

        // 查询改按钮code是否存在
        int codeNum = menuDao.checkedCode(menu.getMenuCode().trim());
        if(codeNum >0){
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.BUTTON_CODE_EXISTS));
        }
        int nameNum = menuDao.checkedName(menu.getTitle().trim());
        if(nameNum >0){
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.BUTTON_DESCRIBE_EXISTS));
        }

        menu.setCreateTime(new Date());
        menu.setType(SysConfigConstants.Menu_Config.TYPE_2);
        menu.setIsPermission(SysConfigConstants.STATUS_0);
        return menuMapper.insert(menu);
    }

    @Override
    public int updateButton(Menu menu) {
        // 查询改按钮code是否存在
        int codeNum = menuDao.checkedCode(menu.getMenuCode().trim());
        if(codeNum >0){
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.BUTTON_CODE_EXISTS));
        }

        int nameNum = menuDao.checkedName(menu.getTitle().trim());
        if(nameNum >0){
            throw new ApiException(copyWriterConfigUtil.getCopyWriterValue(CopyWriterConstant.BUTTON_DESCRIBE_EXISTS));
        }

        menu.setUpdateTime(new Date());
        return menuMapper.updateByPrimaryKeySelective(menu);
    }

    @Override
    public int deleteButton(Integer id) {
        return menuMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int updateButtonStatus(Integer id) {
        Menu menu = menuMapper.selectByPrimaryKey(id);
        if(menu.getIsPermission().equals(SysConfigConstants.STATUS_1)){
            menu.setIsPermission(SysConfigConstants.STATUS_0);
        }else{
            menu.setIsPermission(SysConfigConstants.STATUS_1);
        }
        menu.setUpdateTime(new Date());
        return menuMapper.updateByPrimaryKeySelective(menu);
    }

    @Override
    public void editButton(Integer id, String apiCode) {
        menuDao.editButton(id, apiCode);
    }

    /**
     * 修改菜单层级
     */
    private void updateLevel(Menu menu) {
        if (StringUtils.isBlank(menu.getMenuPreCode())) {
            //没有父菜单时为一级菜单
            menu.setMenuLevel(SysConfigConstants.Menu_Config.TYPE_1);
        } else {
            //有父菜单时选择根据父菜单level设置
            MenuExample menuExample = new MenuExample();
            menuExample.createCriteria().andMenuCodeEqualTo(menu.getMenuPreCode());
            List<Menu> parentMenus = menuMapper.selectByExample(menuExample);
            if(parentMenus!=null && parentMenus.size()>0){
                int menuLevel =  parentMenus.get(0).getMenuLevel();
                int menuLevel_after = menuLevel+1;
                menu.setMenuLevel((byte)menuLevel_after);
            }else{
                menu.setMenuLevel(SysConfigConstants.Menu_Config.TYPE_1);
            }
        }
    }

    /**
     * 将Menu转化为MenuTreeResponse并设置children属性
     */
    private MenuTreeResponse covertMenuNode(Menu menu, List<Menu> menuList) {
        MenuTreeResponse menuTreeResponse = new MenuTreeResponse();
        BeanUtils.copyProperties(menu, menuTreeResponse);
        List<MenuTreeResponse> children = menuList.stream()
                .filter(subMenu -> String.valueOf(menu.getId()).equals(subMenu.getMenuPreCode()))
                .map(subMenu -> covertMenuNode(subMenu, menuList)).collect(Collectors.toList());
        menuTreeResponse.setChildren(children);
        return menuTreeResponse;
    }
}
